<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        class Queue {
            constructor(worker) {
                let taskQueue = []
                let runCount = 0

                // 题目一
                // this.call = function (param) {
                //     return new Promise(async (resolve) => {
                //         if (runCount === 0) {
                //             taskQueue.push({ param, resolve })
                //             runTask()
                //         }
                //         else taskQueue.push({ param, resolve })
                //     })
                // }
                // let runTask = async function () {
                //     runCount++
                //     let item = taskQueue.shift()
                //     const { param, resolve } = item;
                //     let res = await worker(param)
                //     resolve(res)
                //     runCount--
                //     if (taskQueue.length) runTask()
                // }

                // 题目二
                this.call = function (param) {
                    return new Promise(async (resolve) => {
                        const fn = async () => await worker(param)
                        const obj = { resolve, fn, res: undefined }
                        taskQueue.push(obj)
                        runTask(obj)
                    })
                }
                let runTask = async function (obj) {
                    const { fn } = obj
                    obj.res = await fn()
                    if (taskQueue.indexOf(obj) === 0)
                        for (let i = 0; i < taskQueue.length; i++) {
                            if (taskQueue[i].res !== undefined) {
                                taskQueue[i].resolve(taskQueue[i].res)
                                taskQueue.splice(i, 1)
                                i--
                            }
                        }
                }
            };

        }


        //use
        const queue = new Queue(async (param) => {
            await new Promise(resolve => setTimeout(resolve, 1000 * param));
            return param;
        });

        // // 题目一
        // queue.call(1).then(console.log);  // 第1s
        // queue.call(2).then(console.log);  // 第3s
        // queue.call(3).then(console.log);  // 第6s

        // 题目二
        queue.call(1).then(console.log);  // 第1s
        queue.call(3).then(console.log);  // 第3s
        queue.call(2).then(console.log);  // 第3s

    </script>
</body>

</html>